package cn.data.collection.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import cn.data.collection.constant.BusConstant;
import cn.data.collection.constant.CommonData;
import cn.data.collection.constant.DefaultConstant;
import cn.data.collection.constant.InitPropertiesConstant;
import cn.data.collection.constant.NumberConstant;
import cn.data.collection.exception.CollectionException;
import cn.smy.dama2.CrackValidateCode;

public class HttpClientUtils {
	// 创建httpclient实例
	private CloseableHttpClient httpClient = null;
	private PoolingHttpClientConnectionManager httpClientConnectionManager = null;

	public HttpClientUtils() {
		super();
	}

	/**
	 * 方法名：initHttpClient 描述：创建httpClient连接池，并初始化httpclient
	 */
	public void initHttpClient() {
		// 初始化httpclient客户端
		HttpClientBuilder objHttpClientBuilder = HttpClients.custom();
		String proxoolConnectionHost = null;
		int proxoolConnectionPort = NumberConstant.ZERO;
		try {
			proxoolConnectionHost = PropertiesUtils.getInstance().getINITDATA().getProperty(InitPropertiesConstant.HTTP_PROXOOL_CONNECTION_HOST);
			proxoolConnectionPort = Integer.valueOf(PropertiesUtils.getInstance().getINITDATA().getProperty(InitPropertiesConstant.HTTP_PROXOOL_CONNECTION_PORT));
		} catch (Exception e) {}
		
		if(!StringUtil.isRealEmpty(proxoolConnectionHost)){
			objHttpClientBuilder.setProxy(new HttpHost(proxoolConnectionHost,proxoolConnectionPort));
		}
		// 初始化httpclient客户端
		httpClient = objHttpClientBuilder.setConnectionTimeToLive(DefaultConstant.HTTP_REQUEST_TIMEOUTE, TimeUnit.SECONDS).build();
	}
	
	
	/**
	 * 方法名：initHttpClient 描述：创建httpClient连接池，并初始化httpclient
	 */
	public void initHttpClientPools() {
		// 创建httpclient连接池
		httpClientConnectionManager = new PoolingHttpClientConnectionManager();
		httpClientConnectionManager.setMaxTotal(DefaultConstant.HTTP_MAX_TOTAL);// 设置连接池线程最大数量
		httpClientConnectionManager.setDefaultMaxPerRoute(DefaultConstant.HTTP_MAX_ROUTE_TOTAL); // 设置单个路由最大的连接线程数量
		// 创建http request的配置信息
		RequestConfig requestConfig = RequestConfig.custom()
				.setConnectionRequestTimeout(DefaultConstant.HTTP_REQUEST_TIMEOUTE)
				.setSocketTimeout(DefaultConstant.HTTP_REQUEST_SOCKET_TIMEOUTE).build();
		// 设置重定向策略
		LaxRedirectStrategy redirectStrategy = new LaxRedirectStrategy();
		HttpClientBuilder objHttpClientBuilder = HttpClients.custom();
		objHttpClientBuilder.setConnectionManager(httpClientConnectionManager).setDefaultRequestConfig(requestConfig).setUserAgent(DefaultConstant.CHROME_USERAGENT).setRedirectStrategy(redirectStrategy);
		
		String proxoolConnectionHost = null;
		int proxoolConnectionPort = NumberConstant.ZERO;
		try {
			proxoolConnectionHost = PropertiesUtils.getInstance().getINITDATA().getProperty(InitPropertiesConstant.HTTP_PROXOOL_CONNECTION_HOST);
			proxoolConnectionPort = Integer.valueOf(PropertiesUtils.getInstance().getINITDATA().getProperty(InitPropertiesConstant.HTTP_PROXOOL_CONNECTION_PORT));
		} catch (Exception e) {
		}
		
		if(!StringUtil.isRealEmpty(proxoolConnectionHost)){
			objHttpClientBuilder.setProxy(new HttpHost(proxoolConnectionHost,proxoolConnectionPort));
		}
		// 初始化httpclient客户端
		httpClient = objHttpClientBuilder.build();
	}

	/**
	 * 
	 * @Title: postForm
	 * @Description: TODO Post Form表单
	 * @param @param url
	 * @param @param paramMap
	 * @param @return
	 * @param @throws Exception 设定文件
	 * @return String 返回类型
	 * @throws
	 */
	public String postForm(final String url, final Map<String, String> paramMap) throws CollectionException {
		HttpPost httpPost = new HttpPost(url);
		List<NameValuePair> nvps = new ArrayList<NameValuePair>();
		for (Map.Entry<String, String> entry : paramMap.entrySet()) {
			nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
		}
		try {
			// 设置表单提交编码为UTF-8
			httpPost.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8));
			ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
				@Override
				public String handleResponse(final HttpResponse response) throws ClientProtocolException, IOException {
					int status = response.getStatusLine().getStatusCode();
					if (status >= 200 && status < 300) {
						HttpEntity entity = response.getEntity();
						return entity != null ? EntityUtils.toString(entity,"UTF-8") : null;
					} else {
						throw new ClientProtocolException("Unexpected response status: " + status);
					}
				}

			};
			return httpClient.execute(httpPost, responseHandler);
		} catch (Exception e) {
			httpPost.releaseConnection();
			httpPost.abort();
			throw new CollectionException(BusConstant.E_10001.getCode(), e);
		} finally {
			if (httpPost != null) {
				httpPost.releaseConnection();
				httpPost.abort();
				httpPost = null;
			}
		}
	}

	/**
	 * 描述：根据给定的url下载信息
	 * 
	 * @param url
	 * @return
	 * @throws Exception
	 */
	public String loadUrl(final String url) throws Exception {
		if (StringUtil.isRealEmpty(url)) {
			return null; // 如果url为空或者null，则返回src空值
		}

		HttpGet httpGet = new HttpGet(url);
		try {
			ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
				@Override
				public String handleResponse(final HttpResponse response) throws ClientProtocolException, IOException {
					int status = response.getStatusLine().getStatusCode();
					if (status >= 200 && status < 300) {
						HttpEntity entity = response.getEntity();
						return entity != null ? EntityUtils.toString(entity,"GBK") : null;
					} else {
						throw new ClientProtocolException("Unexpected response status: " + status);
					}
				}

			};
			return httpClient.execute(httpGet, responseHandler);
		} catch (Exception e) {
			httpGet.releaseConnection();
			httpGet.abort();
			throw new CollectionException(BusConstant.E_10001.getCode(), e);
		} finally {
			httpGet.releaseConnection();
			httpGet.abort();
		}
	}
	
	public void downloadImg(String strUrl, String fileName) throws Exception {
		URL url = new URL(strUrl);
		URI uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);
		HttpGet httpGet = new HttpGet(uri);
		File file = new File(PropertiesUtils.getInstance().getINITDATA().getProperty(InitPropertiesConstant.DAMA_IMG_LOCATION));
		FileOutputStream fos = null;
		try {
			
			// 客户端开始向指定的网址发送请求
			HttpResponse response = httpClient.execute(httpGet);
			InputStream inputStream = response.getEntity().getContent();
			if (!file.exists()) {
				file.mkdirs();
			}

			fos = new FileOutputStream(PropertiesUtils.getInstance().getINITDATA().getProperty(InitPropertiesConstant.DAMA_IMG_LOCATION)+"/"+ fileName + ".png");
			byte[] data = new byte[1024];
			int len = 0;
			while ((len = inputStream.read(data)) != -1) {
				fos.write(data, 0, len);
			}
		} catch (IOException e) {
			throw e;
		} finally {
			if (fos != null) {
				fos.close();
			}
		}
	}


	public void releaseConnection() {
		if (httpClient != null) {
			try {
				httpClient.close();
				httpClient = null;
			} catch (IOException e) {
			}
		}
	}
	
	/**
	 * inputstream转换成byte数组，然后将这个byte数组转成字符串（随便哪种编码方式）
	 * 然后解析字符串中的编码方式。再利用这种编码方式将之前的byte数组转成正确的网页字符串
	 * 
	 * @throws Exception
	 */
	public Document instr2Jsoup(String src) throws Exception {
		if(StringUtil.isRealEmpty(src)){
			return null;
		}
		return Jsoup.parse(src);
	}

	/**
	 * inputstream转换成byte数组，然后将这个byte数组转成字符串（随便哪种编码方式）
	 * 然后解析字符串中的编码方式。再利用这种编码方式将之前的byte数组转成正确的网页字符串
	 * 
	 * @throws Exception
	 */
	public Document instr2Jsoup(InputStream inputStream) throws Exception {
		byte[] contentBytes = IOUtils.toBytes(inputStream);
		String src = new String(contentBytes, "UTF-8");
		return Jsoup.parse(src);
	}

	public static void main(String[] args) throws Exception {
		System.out.println(StringUtil.isRealEmpty(null));
		String main_url = "http://gsxt.gdgs.gov.cn";
		String strRadom = String.valueOf(Math.random());
		String url = "http://gsxt.gdgs.gov.cn/aiccips/verify.html?random="+strRadom;

		HttpClientUtils httpClientUtils = new HttpClientUtils();httpClientUtils.initHttpClient();
		long startGetMainPagTime = System.currentTimeMillis();
		httpClientUtils.loadUrl(main_url);
		long endGetMainPagTime = System.currentTimeMillis();
		System.out.println("初始化首页耗费时间:"+(endGetMainPagTime-startGetMainPagTime)+"毫秒！");
		httpClientUtils.downloadImg(url, strRadom);
		long downloadImgTime = System.currentTimeMillis();
		System.out.println("下载图片耗费时间:"+(downloadImgTime-endGetMainPagTime)+"毫秒！");
		
		CommonData.DAMA_SOFTWARE_ID = "cbf7d01368041ac3127df4aaae0e73c7";
		CommonData.DAMA_USER_NAME = "test";
		CommonData.DAMA_PASSWORD = "test";
		String validateCode = CrackValidateCode.getInstance().getValidateCode(strRadom);
		System.out.println("validateCode:"+validateCode);
		long damaTime = System.currentTimeMillis();
		System.out.println("打码耗费时间:"+(damaTime-downloadImgTime)+"毫秒！");
		
		String checkCodeUrl = "http://gsxt.gdgs.gov.cn/aiccips/CheckEntContext/checkCode.html";
		Map<String, String> checkCodeParamMap = new HashMap<String, String>();
		checkCodeParamMap.put("textfield","441700000022617");
		checkCodeParamMap.put("code",validateCode);
		String strCheckCode = httpClientUtils.postForm(checkCodeUrl, checkCodeParamMap).toString();
		System.out.println("获取到的验证码:"+strCheckCode);
		System.out.println("修正的验证码:"+UnicodeCharUtil.getFixStr(java.net.URLDecoder.decode(strCheckCode.substring("{\"flag\":\"1\",\"textfield\":\"".length(), strCheckCode.length()-2)).replaceAll("\u003d", "=")));
		
		String getInfoUrl = "http://gsxt.gdgs.gov.cn/aiccips/CheckEntContext/showInfo.html";
		Map<String, String> getInfoParamMap = new HashMap<String, String>();
		getInfoParamMap.put("textfield",UnicodeCharUtil.getFixStr(java.net.URLDecoder.decode(strCheckCode.substring("{\"flag\":\"1\",\"textfield\":\"".length(), strCheckCode.length()-2)).replaceAll("\u003d", "=")));
		getInfoParamMap.put("code",validateCode);
		String strInfo = httpClientUtils.postForm(getInfoUrl, getInfoParamMap);
		System.out.println("获取到的企业为:"+strInfo);
		
		test(httpClientUtils,strInfo);
//		Document doc = httpClientUtils.instr2Jsoup(strInfo);
//		String src = httpClientUtils.loadUrl(url);
//		Document doc = httpClientUtils.instr2Jsoup(src);
//		Elements elements = doc.select(".border");
//		System.out.println(elements.get(0).select("b").text());
//		System.out.println(elements.get(0).select(".font06").get(1).text().substring("注册号/统一社会信用代码：".length()));
//		System.out.println();
	}
	
	public static void test(HttpClientUtils httpClientUtils,String src) throws Exception{
		Document doc = httpClientUtils.instr2Jsoup(src);
		System.out.println(doc.select(".list a").html());
		System.out.println();
	}
}
